#ifndef _COMPREHENSION_H_
#define _COMPREHENSION_H_
#include "ast/comprehensionType.h"
#include "ast/exprType.h"
#include "ast/exprType.h"
class IVisitor;
class Comprehension;
typedef QSharedPointer<Comprehension> ComprehensionPtr;

class Comprehension: public comprehensionType
{
public:
    explicit Comprehension(const exprTypePtr& target, const exprTypePtr& iter, const ExprTypeList& ifs, int nodeId=-1);
    virtual ~Comprehension();
    
    
    exprTypePtr target();
    void setTarget(const exprTypePtr& target);
    
    exprTypePtr iter();
    void setIter(const exprTypePtr& iter);
    
    ExprTypeList ifs();
    void setIfs(const ExprTypeList& ifs);
    
    
    virtual QString type() const;
    virtual QString toString() const;
    virtual void accept(IVisitor* visitor, const SimpleNodePtr& node);
    virtual void traverse(IVisitor* visitor);
private:
    exprTypePtr _target;
    exprTypePtr _iter;
    ExprTypeList _ifs;
};



typedef QListIterator<ComprehensionPtr> ComprehensionPtrListIterator;

class ComprehensionList: public QList<ComprehensionPtr>
{
public:
    inline ComprehensionList() { }
    inline explicit ComprehensionList(ComprehensionPtr i) { append(i); }
    inline ComprehensionList(const ComprehensionList &l) : QList<ComprehensionPtr>(l) { }
    inline ComprehensionList(const QList<ComprehensionPtr> &l) : QList<ComprehensionPtr>(l) { }

    inline ComprehensionList operator+(const ComprehensionList &other) const
    { ComprehensionList n = *this; n += other; return n; }
    inline ComprehensionList &operator<<(ComprehensionPtr it)
    { append(it); return *this; }
    inline ComprehensionList &operator<<(const ComprehensionList &l)
    { *this += l; return *this; }

    QString toString() const
    {
        QString str("ComprehensionList(");
        foreach(ComprehensionPtr it, *this){
            if (it != NULL){
                str += it->toString()+",";
            }
        }
        str += ")";
        return str;
    }

    void traverse(IVisitor* visitor)
    {
        foreach(ComprehensionPtr it, *this){
            if (it != NULL){
                it->accept(visitor, it);
            }
        }
    }
};



#endif